import 'package:flutter/material.dart';

class SimpleTest extends StatefulWidget {
  @override
  _SimpleTestState createState() => _SimpleTestState();
}

class _SimpleTestState extends State<SimpleTest> with TickerProviderStateMixin {
  Offset _translateOffset = Offset(0, 0);

  late AnimationController _controller;
  late Animation<Offset> _animation;

  final Duration _duration = Duration(milliseconds: 1000);

  final Curve _curve = Curves.easeIn;

  _setTranslateOffset() {
    if (mounted) {
      setState(() {
        _translateOffset = _animation.value;
      });
    }
  }

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: _duration,
    );

    _animation = Tween<Offset>(
      begin: Offset(0, 0),
      end: Offset(0, -400),
    ).animate(CurvedAnimation(
      curve: _curve,
      parent: _controller,
    ));

    _animation.addListener(_setTranslateOffset);
  }

  @override
  void dispose() {
    _controller.dispose();

    _animation.removeListener(_setTranslateOffset);

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.symmetric(horizontal: 8),
      height: 300,
      child: Column(
        children: [
          Expanded(
            child: Container(
              alignment: Alignment.bottomCenter,
              // 这两个的效果都是一样的
              // child: Transform.translate(
              //   offset: _translateOffset,
              //   child: Container(
              //     width: 50,
              //     height: 50,
              //     color: Colors.blueGrey,
              //   ),
              // ),
              child: MyTransition(
                position: _animation,
                child: Container(
                  width: 50,
                  height: 50,
                  color: Colors.blueGrey,
                ),
              ),
            ),
          ),
          TextButton(
            onPressed: () {
              if (_controller.status == AnimationStatus.dismissed ||
                  _controller.status == AnimationStatus.reverse) {
                _controller.forward();
              } else {
                _controller.reverse();
              }
            },
            child: Text('点击'),
          ),
        ],
      ),
    );
  }
}

/// AnimatedWidget 会自动帮忙处理 listenable 的 addListener 和 setState
class MyTransition extends AnimatedWidget {
  MyTransition({
    Key? key,
    required Animation<Offset> position,
    this.child,
  }) : super(
          key: key,
          listenable: position,
        );

  Animation<Offset> get position => listenable as Animation<Offset>;

  final Widget? child;

  @override
  Widget build(BuildContext context) {
    return Transform.translate(
      offset: position.value,
      child: child,
    );
  }
}
